﻿using System;
using System.Collections.Generic;
using System.Linq;
using EP.Base.BaseService.Manager.Config.Enum;
using EP.Base.BaseService.Manager.Interface;
using EP.Base.BaseService.Manager.Interface.Business;
using EP.Base.BaseService.Manager.Interface.Common;
using EP.Base.BaseService.Manager.Interface.Data;
using EP.Base.BaseService.Manager.Model;
using EP.Base.BaseService.Manager.Model.Entity;

namespace EP.Base.BaseService.Manager.Business.Task
{
    /// <summary>
    /// 删除索引的检测任务（值检测出要删除的索引并存储到数据库中，等待确认为时间到达后执行删除）
    /// 使用了新的获取索引的方法 see line 60
    /// </summary>
    public class CheckDeleteIndexTask_New : IEsIndexHandelTask
    {
        private readonly ILog _log;
        private readonly IJson _json;
        private readonly IEsClusters _esClusters;
        private readonly IIndexConfigs _indexConfigs;
        private readonly IEsData _esData;
        private readonly IIndexDateExtract _indexDateExtract;
        private readonly IIndexDeleteLogs _indexDeleteLogs;
        public CheckDeleteIndexTask_New(ILog log, IEsClusters esClusters, IIndexConfigs indexConfigs, IEsData esData, IJson json, IIndexDateExtract indexDateExtract, IIndexDeleteLogs indexDeleteLogs)
        {
            _log = log;
            _esClusters = esClusters;
            _indexConfigs = indexConfigs;
            _esData = esData;
            _json = json;
            _indexDateExtract = indexDateExtract;
            _indexDeleteLogs = indexDeleteLogs;
        }

        public bool Exec(EsTaskConfig taskConfig)
        {
            _log.Debug("执行清理任务 id=" + taskConfig.Id);

            //index信息
            var indexConfig = _indexConfigs.Get(taskConfig.IndexConfigId);
            if (indexConfig == null)
            {
                _log.WarnFormat("IndexConfigId={0},未找到对应的indexConfig数据！", taskConfig.IndexConfigId);
                return false;
            }
            //es集群信息
            var esClustersInfo = _esClusters.Get(indexConfig.ClusterId);
            if (esClustersInfo == null)
            {
                _log.WarnFormat("ClusterId={0},未找到对应的esClustersInfo数据！", indexConfig.ClusterId);
                return false;
            }
            //配置
            var deleteConfig = _json.DeserializeObject<CheckDeleteIndexTaskConfig>(taskConfig.Configs);

            //通过别名找到所有的索引
            IEnumerable<string> indices = _esData.GetAllIndexByIndexPreFixOrAlias(esClustersInfo.ServiceHostArr, indexConfig.Alias);
            if (indices == null || !indices.Any())
                return true;
            //根据规则得到索引的创建时间
            var indexAndTimes= _indexDateExtract.Extract(deleteConfig.IndexDateExtractReg, indices);


            foreach (var indexAndTime in indexAndTimes)
            {
                var indexName = indexAndTime.Key;
                var time = indexAndTime.Value;
                var needDelete = CheckIndexNeedDelete(deleteConfig,time);

                _log.DebugFormat("index={0},time={1},needDelete={2}", indexName, time.ToString("yyyy-MM-dd HH:mm:ss"), needDelete);
                if (needDelete)
                {
                    _indexDeleteLogs.AddByNoIndex(new IndexDeleteLog
                    {
                        IndexName=indexName,
                        CreateTime = DateTime.Now,
                        State = (short)(deleteConfig.NoConfirmation ? EnumIndexDeleteLogState.NeedDelete : EnumIndexDeleteLogState.WaitConfirmation),
                        IndexCreateTime = time,
                        IndexConfigId = taskConfig.IndexConfigId
                    });
                }

            }
            return true;
        }

        private bool CheckIndexNeedDelete(CheckDeleteIndexTaskConfig config, DateTime createTime)
        {
            var nowTime = DateTime.Now;
            var year = nowTime.Year;
            var month = nowTime.Month;
            var day = nowTime.Day;
            if (config.Unit == (short) EnumDeleteIndexTaskUnit.Day)
            {
                return createTime.AddDays(config.MaxDValue) < new DateTime(year, month, day);
            }
            if (config.Unit == (short) EnumDeleteIndexTaskUnit.Month)
            {
                return createTime.AddMonths(config.MaxDValue) < new DateTime(year, month, 1);
            }
            if (config.Unit == (short)EnumDeleteIndexTaskUnit.Year)
            {
                return createTime.AddYears(config.MaxDValue) < new DateTime(year, 1, 1);
            }
            return false;
        }
    }
}
